﻿using laohan.Common.json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace laohan.Common.Common
{
    /// <summary>
    /// Http操作帮助类
    /// </summary>
    public partial class API
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string Get(string url, string accessToken = "")
        {
            string responseText = string.Empty;

            var request = (HttpWebRequest)WebRequest.Create(url);

            if (!string.IsNullOrEmpty(accessToken))
            {
                request.Headers.Add("Authorization", "Bearer " + accessToken);
            }

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                var reader = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8);

                responseText = reader.ReadToEnd();

                reader.Close();
            }

            request = null;

            return responseText;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        public static string GetDownload(string url, string accessToken = "")
        {
            var request = (HttpWebRequest)WebRequest.Create(url);

            if (!string.IsNullOrEmpty(accessToken))
            {
                request.Headers.Add("Authorization", "Bearer " + accessToken);
            }

            MemoryStream ms = new MemoryStream();

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                Stream responseStream = response.GetResponseStream();

                byte[] bArr = new byte[1024];

                int size = responseStream.Read(bArr, 0, (int)bArr.Length);

                while (size > 0)
                {
                    ms.Write(bArr, 0, size);

                    size = responseStream.Read(bArr, 0, (int)bArr.Length);
                }

                ms.Close();
                responseStream.Close();
            }

            var content = ms.ToArray();

            var json = new NTJsonHelper();

            var fileVo = new
            {
                code = "200",
                msg = "处理数据成功！",
                data = new
                {
                    fileContent = content
                }
            };

            return json.Serialize(fileVo);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static string Post(string url, Dictionary<string, object> parameters = null, string accessToken = "")
        {
            string responseText = string.Empty;

            var request = (HttpWebRequest)WebRequest.Create(url);

            request.Method = "POST";////Post请求方式  
            request.ContentType = "application/x-www-form-urlencoded";// 内容类型  

            if (!string.IsNullOrEmpty(accessToken))
            {
                request.Headers.Add("Authorization", "Bearer " + accessToken);
            }

            StringBuilder sb = new StringBuilder();

            if (parameters != null)
            {
                foreach (var item in parameters)
                {
                    string key = System.Web.HttpUtility.UrlEncode(item.Key);
                    string value = System.Web.HttpUtility.UrlEncode(item.Value.ToString());

                    sb.Append(string.Format("{0}={1}&", key, value));
                }

                sb.Remove(sb.Length - 1, 1);
            }

            byte[] payload = Encoding.UTF8.GetBytes(sb.ToString());//将URL编码后的字符串转化为字节  

            request.ContentLength = payload.Length;//设置请求的 ContentLength

            using (System.IO.Stream writer = request.GetRequestStream())
            {
                writer.Write(payload, 0, payload.Length);
                writer.Close();

                var response = (HttpWebResponse)request.GetResponse();

                System.IO.StreamReader myreader = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8);

                responseText = myreader.ReadToEnd();

                myreader.Close();
            }

            request = null;

            return responseText;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="json"></param>
        /// <returns></returns>
        public static string Post(string url, string json, string accessToken = "")
        {
            string responseText = string.Empty;

            var request = (HttpWebRequest)WebRequest.Create(url);

            request.Method = "POST";////Post请求方式  
            request.ContentType = "application/json;charset=UTF-8";// 内容类型  

            if (!string.IsNullOrEmpty(accessToken))
            {
                request.Headers.Add("Authorization", "Bearer " + accessToken);
            }

            byte[] payload = Encoding.UTF8.GetBytes(json);//将URL编码后的字符串转化为字节  

            request.ContentLength = payload.Length;//设置请求的 ContentLength

            using (System.IO.Stream writer = request.GetRequestStream())
            {
                writer.Write(payload, 0, payload.Length);
                writer.Close();

                var response = (HttpWebResponse)request.GetResponse();

                System.IO.StreamReader myreader = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8);

                responseText = myreader.ReadToEnd();

                myreader.Close();
            }

            request = null;

            return responseText;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="parameters"></param>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        public static string PostUploadFiles(string url, Dictionary<string, object> parameters = null, string accessToken = "")
        {
            string responseText = string.Empty;

            var request = (HttpWebRequest)WebRequest.Create(url);

            CookieContainer cookieContainer = new CookieContainer();

            request.CookieContainer = cookieContainer;
            request.AllowAutoRedirect = true;
            request.Method = "POST";////Post请求方式  

            if (!string.IsNullOrEmpty(accessToken))
            {
                request.Headers.Add("Authorization", "Bearer " + accessToken);
            }

            string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线

            request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;

            const string filePartHeaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + "Content-Type: application/octet-stream\r\n\r\n";

            byte[] beginBoundaryBytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");  // 边界符开始。右侧必须要有 \r\n 。
            byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); // 边界符结束。两侧必须要有 --\r\n 。
            byte[] newLineBytes = Encoding.UTF8.GetBytes("\r\n"); //换一行

            MemoryStream memoryStream = new MemoryStream();

            List<string> lstFiles = new List<string>();

            foreach (string fileFullName in parameters.Values)
            {
                if (File.Exists(fileFullName))
                {
                    lstFiles.Add(fileFullName);
                }
            }

            int i = 0;

            foreach (var fileFullName in lstFiles)
            {
                FileInfo fileInfo = new FileInfo(fileFullName);

                string fileName = fileInfo.Name;

                string fileHeaderItem = string.Format(filePartHeaderTemplate, "file", fileName);

                byte[] fileHeaderItemBytes = Encoding.UTF8.GetBytes(fileHeaderItem);

                if (i > 0)
                {
                    // 第一笔及第一笔之后的数据项之间要增加一个换行 
                    memoryStream.Write(newLineBytes, 0, newLineBytes.Length);
                }

                memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length);  // 2.1 写入FormData项的开始边界符
                memoryStream.Write(fileHeaderItemBytes, 0, fileHeaderItemBytes.Length); // 2.2 将文件头写入FormData项中

                int bytesRead;

                byte[] buffer = new byte[1024];

                FileStream fileStream = new FileStream(fileFullName, FileMode.Open, FileAccess.Read);

                while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    memoryStream.Write(buffer, 0, bytesRead);        // 2.3 将文件流写入FormData项中
                }

                i++;
            }

            memoryStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);    // 2.4 写入FormData的结束边界符

            request.ContentLength = memoryStream.Length;

            memoryStream.Position = 0;

            using (Stream requestStream = request.GetRequestStream())
            {
                byte[] tempBuffer = new byte[memoryStream.Length];

                memoryStream.Read(tempBuffer, 0, tempBuffer.Length);

                memoryStream.Close();

                requestStream.Write(tempBuffer, 0, tempBuffer.Length);  // 将内存流中的字节写入 httpWebRequest 的请求流中

                requestStream.Close();

                //发送请求并获取相应回应数据
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;

                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                Stream instream = response.GetResponseStream();

                StreamReader sr = new StreamReader(instream, Encoding.UTF8);
                responseText = sr.ReadToEnd();

                sr.Close();
            }

            return responseText;
        }

        /// <summary>
        /// 获取页面html
        /// </summary>
        /// <param name="url">请求的地址</param>
        /// <param name="encoding">编码方式：utf-8 gbk</param>
        /// <returns></returns>
        public static string HttpGetPageHtml(string url, string encoding)
        {
            string pageHtml = string.Empty;

            try
            {
                using (WebClient MyWebClient = new WebClient())
                {
                    Encoding encode = Encoding.GetEncoding(encoding);

                    MyWebClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36");
                    MyWebClient.Credentials = CredentialCache.DefaultCredentials;

                    var pageData = MyWebClient.DownloadData(url); //从指定网站下载数据

                    pageHtml = encode.GetString(pageData);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("获取网页内容error:" + ex.Message);
            }

            return pageHtml;
        }

        /// <summary>
        /// 从html中通过正则找到ip信息(只支持ipv4地址)
        /// </summary>
        /// <param name="pageHtml"></param>
        /// <returns></returns>
        public static string GetIPFromHtml(string pageHtml)
        {
            string reg = @"(?:(?:(25[0-5])|(2[0-4]\d)|((1\d{2})|([1-9]?\d)))\.){3}(?:(25[0-5])|(2[0-4]\d)|((1\d{2})|([1-9]?\d)))";//验证ipv4地址
            string ip = "";

            Match m = Regex.Match(pageHtml, reg);

            if (m.Success)
            {
                ip = m.Value;
            }
            return ip;
        }

        /// <summary>
        /// 获取外网ip地址
        /// </summary>
        /// <returns></returns>
        public static string GetInternetIp()
        {
            var html = HttpGetPageHtml("https://www.ip.cn/api/index?ip=&type=0", "utf-8");

            var json = new NTJsonHelper();

            var ipInfo = json.Deserialize<IPInfo>(html);

            return string.Format($"ip:{ipInfo.ip} 地址：{ipInfo.address}");
        }
    }
}